// excerpts from http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#include "Buffer.h"
#include "logging/Logging.h"

#include <errno.h>
#include <memory.h>
#include <sys/uio.h>

using namespace learnmuduo;

ssize_t Buffer::readFd(int fd, int* savedErrno)
{
  char extrabuf[65536];                                                                 // 栈上临时缓冲
  struct iovec vec[2];                                                                  // 两段式缓冲描述
  const size_t writable = writableBytes();                                              // 当前缓冲剩余可写空间
  vec[0].iov_base = begin()+writerIndex_;                                               // 第一段指向主缓冲可写区
  vec[0].iov_len = writable;                                                            // 第一段长度
  vec[1].iov_base = extrabuf;                                                           // 第二段指向临时缓冲
  vec[1].iov_len = sizeof extrabuf;                                                     // 第二段长度
  const ssize_t n = readv(fd, vec, 2);                                     // 分散读取数据
  if (n < 0) {
    *savedErrno = errno;                                                                // 出错时保存 errno
  } else if (muduo::implicit_cast<size_t>(n) <= writable) {
    writerIndex_ += n;                                                                  // 数据全部写入主缓冲
  } else {
    writerIndex_ = buffer_.size();                                                      // 主缓冲写满
    append(extrabuf, n - writable);                                           // 追加剩余数据并可能扩容
  }
  return n;                                                                             // 返回读取字节数或错误
}